#include"Thread.hpp"
#include"RingQueue.hpp"
#include"Task.hpp"
#include<cstdlib>
#include<ctime>
#include<unistd.h>

using namespace zzx;

//方法一:参数为类对象
using ringqueue_t = RingQueue<Task>;

//方法二:参数为函数对象
// void print()
// {
//     std::cout<< "hello" << std::endl;
// }
//using ringqueue_t = functional<void()>;

void ProDucer(ringqueue_t& rq, string who)
{
    srand(time(NULL));
    while(true)
    {
        int a = rand() % 30;
        int b = rand() % 20;
        Task t(a, b); //方法一:参数为类对象
        //Task t = print; 方法二:参数为函数对象
        rq.EnQueue(t);
        cout << who << " data: ";
        t.DebugToString();
        sleep(1);
    }
}

void ConSumer(ringqueue_t& rq, string who)
{
    sleep(7);
    while(true)
    {
        Task t;
        rq.PopQueue(&t);
        t.Excute();
        //t(); 
        cout << who << " data: ";
        t.ResultToString();
        sleep(1);
    }
}

void CommonCode(std::vector<thread<ringqueue_t>>* threads, ringqueue_t& rq, int num, fun_c<ringqueue_t&> fc, string s)
{
    for(int i = 0; i < num; i++)
    {
        char* name = new char(64);
        snprintf(name, 64, "%s-%d", s.c_str(), i + 1);
        thread<ringqueue_t> td(fc, rq, name);
        threads->push_back(td);
    }
}

void StartProDucer(std::vector<thread<ringqueue_t>>* threads, ringqueue_t& rq, int num)
{
    CommonCode(threads, rq, num, ProDucer, "producer");
}

void StartConSumer(std::vector<thread<ringqueue_t>>* threads, ringqueue_t& rq, int num)
{
    CommonCode(threads, rq, num, ConSumer, "consumer");
}

void StartAllThread(std::vector<thread<ringqueue_t>>& threads)
{
    for(auto& e : threads)
    {
        e.start();
    }
}

void WaitThread(std::vector<thread<ringqueue_t>>& threads)
{
    for(auto& e : threads)
    {
        e.join();
    }
}

int main()
{

    std::vector<thread<ringqueue_t>> threads; 
    ringqueue_t rq(5); 
    StartProDucer(&threads, rq, 2);  
    StartConSumer(&threads, rq, 3);  
    
    StartAllThread(threads); 
    WaitThread(threads); 

    return 0;
}